#include "StdAfx.h"
#include "util.h"

namespace GPCommon
{

tstd::tstring LoadResourceString(UINT id)
{
  ATL::CString str;
  str.LoadString(id);
  return static_cast<const tstd::char_type *>(str);
}

_bstr_t LoadResourceBSTR(UINT id)
{
  ATL::CStringW str;
  str.LoadString(id);
  return _bstr_t(str.AllocSysString(), false);
}

template <class Elem>
static void StringReplaceT(std::basic_string<Elem> &source, const std::basic_string<Elem> &lookup, const std::basic_string<Elem> &replace)
{
  if (!lookup.empty())
  {
    size_t start = 0;
    while (true)
    {
      size_t pos = source.find(lookup, start);
      if (std::basic_string<Elem>::npos == pos)
      {
        return;
      }
      source.replace(pos, lookup.length(), replace);
      start = pos + replace.length();
    }
  }
}

void StringReplace(std::string &source, const std::string &lookup, const std::string &replace)
{
  return StringReplaceT(source, lookup, replace);
}

void StringReplace(std::wstring &source, const std::wstring &lookup, const std::wstring &replace)
{
  return StringReplaceT(source, lookup, replace);
}

std::string HTMLMakeEscaped(const std::string &orig)
{
  std::string rv = orig;
  StringReplace(rv, "&", "&amp;");
  StringReplace(rv, ">", "&gt;");
  StringReplace(rv, "<", "&lt;");
  StringReplace(rv, "\"", "&quot;");
  StringReplace(rv, "\n", "<br/>");
  StringReplace(rv, "\r", "");
  return rv;
}

std::wstring HTMLMakeEscaped(const std::wstring &orig)
{
  std::wstring rv = orig;
  StringReplace(rv, L"&", L"&amp;");
  StringReplace(rv, L">", L"&gt;");
  StringReplace(rv, L"<", L"&lt;");
  StringReplace(rv, L"\"", L"&quot;");
  StringReplace(rv, L"\n", L"<br/>");
  StringReplace(rv, L"\r", L"");
  return rv;
}

std::string HTMLUnescape(const std::string &orig)
{
  std::string rv = orig;
  StringReplace(rv, "<br/>", "\n");
  StringReplace(rv, "&gt;", ">");
  StringReplace(rv, "&lt;", "<");
  StringReplace(rv, "&quot;", "\"");
  StringReplace(rv, "&amp;", "&");
  return rv;
}

std::wstring HTMLUnescape(const std::wstring &orig)
{
  std::wstring rv = orig;
  StringReplace(rv, L"<br/>", L"\n");
  StringReplace(rv, L"&gt;", L">");
  StringReplace(rv, L"&lt;", L"<");
  StringReplace(rv, L"&quot;", L"\"");
  StringReplace(rv, L"&amp;", L"&");
  return rv;
}

tstd::tstring GetUserDataPath(const tstd::tstring &tail)
{
  tstd::tstring rv;
  LPITEMIDLIST pidl = 0;
  if (S_OK == ::SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl))
  {
    TCHAR szPath[MAX_PATH + 200];
    if (::SHGetPathFromIDList(pidl, szPath))
    {
      rv = szPath;
      if (rv.empty() || (_T('\\') != *rv.rbegin()))
      {
        rv += _T('\\');
      }
      rv += _T("Grym\\");
      rv += tail;
    }
    IMalloc *pMalloc = 0;
    if (SUCCEEDED(::SHGetMalloc(&pMalloc)))
    {
      pMalloc->Free(pidl);
      pMalloc->Release();
    }
  }
  return rv;
}

GrymCore::IRasterPtr LoadResourceRaster(GrymCore::IGrymObjectFactory *pFactory, UINT rcid_png)
{
	ATLASSERT(NULL != pFactory);
	
	GrymCore::IRasterPtr rv;
	
	HRSRC hResource = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(rcid_png), _T("PNG"));
	ATLASSERT(NULL != hResource);
	if (NULL != hResource)
	{
		HGLOBAL hGlobal = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hResource);
		ATLASSERT(NULL != hGlobal);
		if (NULL != hGlobal)
		{
			ULONG size = ::SizeofResource(ATL::_AtlBaseModule.GetResourceInstance(), hResource);
			if (size)
			{
				BYTE *data = static_cast<BYTE *>(::LockResource(hGlobal));
				ATL::CComSafeArray<byte> saBuf(size);
				BYTE HUGEP *pSAMem;
				ATLVERIFY(S_OK == ::SafeArrayAccessData(saBuf.m_psa, (void HUGEP**)(&pSAMem)));
				::memcpy(pSAMem, data, size);
				::SafeArrayUnaccessData(saBuf.m_psa);
				rv = pFactory->CreateRasterFromMemory(saBuf.m_psa);
			}
		}
	}
	return rv;
}

} // namespace GPCommon
